{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.3. Introducing the multidimensional array in NumPy for fast array computations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:42:58.764766Z",
     "start_time": "2023-10-20T12:42:58.617632Z"
    }
   },
   "outputs": [],
   "source": [
    "import random\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:42:58.963591Z",
     "start_time": "2023-10-20T12:42:58.769869Z"
    }
   },
   "outputs": [],
   "source": [
    "n = 1000000\n",
    "x = [random.random() for _ in range(n)]\n",
    "y = [random.random() for _ in range(n)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:42:58.986067Z",
     "start_time": "2023-10-20T12:42:58.978335Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "([0.4848407746999098, 0.2813135408399722, 0.15894186329834004],\n [0.9608481489562518, 0.5354461212653167, 0.2313248430137781])"
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[:3], y[:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:42:59.061004Z",
     "start_time": "2023-10-20T12:42:58.983269Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "[1.4456889236561616, 0.8167596621052888, 0.39026670631211813]"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = [x[i] + y[i] for i in range(n)]\n",
    "z[:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:04.157824Z",
     "start_time": "2023-10-20T12:42:59.071855Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "62.7 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit [x[i] + y[i] for i in range(n)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:04.214818Z",
     "start_time": "2023-10-20T12:43:04.199576Z"
    }
   },
   "outputs": [],
   "source": [
    "xa = np.array(x)\n",
    "ya = np.array(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:04.229631Z",
     "start_time": "2023-10-20T12:43:04.201511Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([0.48484077, 0.28131354, 0.15894186])"
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xa[:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:04.230680Z",
     "start_time": "2023-10-20T12:43:04.206074Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([1.44568892, 0.81675966, 0.39026671])"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "za = xa + ya\n",
    "za[:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:11.934709Z",
     "start_time": "2023-10-20T12:43:04.210559Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "948 µs ± 55.8 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit xa + ya"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:14.471017Z",
     "start_time": "2023-10-20T12:43:11.997370Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.09 ms ± 214 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit sum(x)  # pure Python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:16.255930Z",
     "start_time": "2023-10-20T12:43:14.470416Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "217 µs ± 31.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit np.sum(xa)  # NumPy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:16.329053Z",
     "start_time": "2023-10-20T12:43:16.324817Z"
    }
   },
   "outputs": [],
   "source": [
    "d = [abs(x[i] - y[j])\n",
    "     for i in range(1000)\n",
    "     for j in range(1000)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:16.337704Z",
     "start_time": "2023-10-20T12:43:16.330343Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "[0.476007374256342, 0.05060534656540683, 0.25351593168613173]"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d[:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:16.346970Z",
     "start_time": "2023-10-20T12:43:16.335398Z"
    }
   },
   "outputs": [],
   "source": [
    "da = np.abs(xa[:1000, np.newaxis] - ya[:1000])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:16.347521Z",
     "start_time": "2023-10-20T12:43:16.341657Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "array([[0.47600737, 0.05060535, 0.25351593, ..., 0.15265391, 0.1578953 ,\n        0.18661915],\n       [0.67953461, 0.25413258, 0.0499887 , ..., 0.05087332, 0.04563194,\n        0.39014639],\n       [0.80190629, 0.37650426, 0.07238298, ..., 0.173245  , 0.16800361,\n        0.51251806],\n       ...,\n       [0.9300003 , 0.50459828, 0.200477  , ..., 0.30133901, 0.29609763,\n        0.64061208],\n       [0.22997601, 0.19542602, 0.4995473 , ..., 0.39868528, 0.40392667,\n        0.05941222],\n       [0.0816188 , 0.34378322, 0.6479045 , ..., 0.54704248, 0.55228387,\n        0.20776942]])"
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "da"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:22.413410Z",
     "start_time": "2023-10-20T12:43:16.400615Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "74.4 ms ± 1.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit [abs(x[i] - y[j]) \\\n",
    "         for i in range(1000) \\\n",
    "         for j in range(1000)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-20T12:43:34.952430Z",
     "start_time": "2023-10-20T12:43:22.415064Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.52 ms ± 38.7 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit np.abs(xa[:1000, np.newaxis] - ya[:1000])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "python3",
   "language": "python",
   "display_name": "Python 3 (ipykernel)"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
